﻿using SketchUpAPI.NET.Enums;
using SketchUpAPI.NET.SketchUp.Exception;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace SketchUpAPI.NET.Objects
{
    /// <summary>
    /// SketchUP 模型颜色，保存 8 位 RGBA 颜色
    /// </summary>
    /// <remarks>对 SketchUpAPI 中 </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct Color
    {
        #region API 函数
        /// <summary>
        /// 将两个颜色按照权重混合
        /// </summary>
        /// <remarks>结果 = (1 - <paramref name="weight"/>) * <paramref name="color1"/> + <paramref name="weight"/> * <paramref name="color2"/></remarks>
        /// <param name="color1">颜色1</param>
        /// <param name="color2">颜色2</param>
        /// <param name="weight">权重</param>
        /// <param name="blended_color">混合结果</param>
        /// <returns></returns>
        [DllImport(ObjectBase.LIB)]
        static extern SUResult SUColorBlend(Color color1, Color color2, double weight, ref Color blended_color);

        /// <summary>
        /// 获取SketchUp可识别颜色的个数
        /// </summary>
        /// <param name="size"></param>
        /// <returns></returns>
        [DllImport(ObjectBase.LIB)]
        static extern SUResult SUColorGetNumNames(out long size);

        /// <summary>
        /// 获取所有颜色的名字
        /// </summary>
        /// <param name="names"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        [DllImport(ObjectBase.LIB)]
        static extern SUResult SUColorGetNames(IntPtr[] names, long size);

        /// <summary>
        /// 通过名字创建颜色
        /// </summary>
        /// <param name="color"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        [DllImport(ObjectBase.LIB)]
        static extern SUResult SUColorSetByName(ref Color color, [MarshalAs(UnmanagedType.LPUTF8Str)] string name);

        /// <summary>
        /// 通过一个数值创建颜色
        /// </summary>
        /// <remarks>Alpha恒定是255，一个十六进制颜色 0x66ccff 对应的rgb 是 (102, 204, 255) </remarks>
        /// <param name="color"></param>
        /// <param name="value">整数或十六进制表示的颜色</param>
        /// <returns></returns>
        [DllImport(ObjectBase.LIB)]
        static extern SUResult SUColorSetByValue(ref Color color, long value);
        #endregion

        /// <summary>
        /// SketchUp 全部颜色的名字
        /// </summary>
        public static List<string> Names
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUColorGetNumNames(out long size));
                StringRef[] stringRefs = new StringRef[size];
                for (int i = 0; i < size; i++)
                {
                    stringRefs[i] = StringRef.Empty;
                }
                IntPtr[] ptrs = stringRefs.Select(sr => sr.Id).ToArray();
                SketchUpExceptionHelper.ThrowSUResult(SUColorGetNames(ptrs, size));
                return stringRefs.Select(sr => sr.Dispose()).ToList();
            }
        }

        public byte red;
        public byte green;
        public byte blue;
        public byte alpha;

        public Color(byte r, byte g, byte b, byte a)
        {
            red = r; green = g; blue = b; alpha = a;
        }

        /// <summary>
        /// 通过数值创建颜色
        /// </summary>
        /// <param name="value">整数或十六进制数</param>
        /// <returns></returns>
        public static Color Create(long value)
        {
            Color c = new Color();
            SketchUpExceptionHelper.ThrowSUResult(SUColorSetByValue(ref c, value));
            return c;
        }

        /// <summary>
        /// 通过名字创建颜色
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static Color Create(string name)
        {
            Color c = new Color();
            SketchUpExceptionHelper.ThrowSUResult(SUColorSetByName(ref c, name));
            return c;
        }

        /// <summary>
        /// 将两个颜色按照权重混合
        /// </summary>
        /// <param name="color1"></param>
        /// <param name="color2"></param>
        /// <param name="color2Weight"></param>
        public static Color Blend(Color color1, Color color2, double color2Weight)
        {
            Color res = new Color();
            SketchUpExceptionHelper.ThrowSUResult(SUColorBlend(color1, color2, color2Weight, ref res));
            return res;
        }
    }
}